package com.demo.javase.day69;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @Author bug菌
 * @Date 2023-11-06 16:00
 */
public class ConcurrentLinkedQueueTest {
    public static void main(String[] args) throws InterruptedException {
        final int THREAD_COUNT = 1000;
        final int ELEMENT_COUNT = 100;
        ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);

        ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();

        // testAdd
        for (int i = 0; i < ELEMENT_COUNT; i++) {
            executorService.execute(() -> {
                for (int j = 0; j < ELEMENT_COUNT; j++) {
                    queue.offer(j);
                }
            });
        }

        executorService.shutdown();
        executorService.awaitTermination(10, TimeUnit.SECONDS);

        assert ELEMENT_COUNT * ELEMENT_COUNT == queue.size();

        // testPoll
        executorService = Executors.newFixedThreadPool(THREAD_COUNT);
        for (int i = 0; i < ELEMENT_COUNT; i++) {
            queue.offer(i);
        }

        for (int i = 0; i < THREAD_COUNT; i++) {
            executorService.execute(() -> {
                for (int j = 0; j < ELEMENT_COUNT; j++) {
                    Integer element = queue.poll();
                    assert element != null;
                }
            });
        }

        executorService.shutdown();
        executorService.awaitTermination(10, TimeUnit.SECONDS);

        System.out.println("queue.size() = " + queue.size());
    }
}
